package org.vogelsk.blue.gui;

import org.vogelsk.blue.R;
import org.vogelsk.blue.app.BlueSquireEngine;
import org.vogelsk.blue.app.GameThread;
import org.vogelsk.blue.auxillary.BlueLevels;
import org.vogelsk.blue.objects.Ball;
import org.vogelsk.blue.objects.Brick;
import org.vogelsk.blue.objects.Goodie;
import org.vogelsk.blue.objects.GoodieType;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

/**
 * 
 * Custom surface view made for the game. Also, initiates game engine and game thread.
 * 
 * @author dejan.dosic
 *
 */
public class BlueSurfaceView extends SurfaceView {

	private SurfaceHolder holder;
	private Bitmap ballImage;
	private Bitmap plasmaBallImage;
	private Bitmap paddleImage;
	private Bitmap paddleIcon;
	private Bitmap brickImage;
	private Bitmap brickImage2;
	private Bitmap brickImage3;
	private Bitmap brickImage4;
	private Bitmap greenPowerUpImage;
	private Bitmap threeBall;
	private Bitmap skullImage;
	private Bitmap moneyImage;
	private Bitmap arrowImage;
	private Bitmap plasmaImage;
	private Bitmap backgroundImage;
	private GestureDetector gestureDetector;

	private GameThread gameLoopThread;
	private BlueSquireEngine gameEngine;
	private Bitmap paddleLarge;
    
	public BlueSurfaceView(BlueSquireActivity context, Bitmap ballImage,
			Bitmap paddleImage, Bitmap brickImage1, Bitmap brickImage2,
			Bitmap brickImage3, Bitmap brickImage4, Bitmap paddleLarge,Bitmap paddleIcon, Bitmap greenPowerUpImage, Bitmap threeBall, Bitmap plasmaBall, Bitmap skull, Bitmap money, Bitmap arrow, Bitmap plasma) {
		super(context);

		backgroundImage = BitmapFactory.decodeResource(getResources(),R.drawable.blue_sky);

		this.ballImage =  ballImage;
		this.plasmaBallImage = plasmaBall;
		this.brickImage = brickImage1;
		this.brickImage2 = brickImage2;
		this.brickImage3 = brickImage3;
		this.brickImage4 = brickImage4;
		this.paddleImage = paddleImage;
		this.paddleLarge = paddleLarge;
		this.paddleIcon = paddleIcon;
		this.threeBall = threeBall;
		this.skullImage = skull;
		this.moneyImage = money;
		this.arrowImage = arrow;
		this.plasmaImage = plasma;
		this.greenPowerUpImage = greenPowerUpImage;
		holder = getHolder();
		gameLoopThread = new GameThread(this);
		gameLoopThread.setRunning(true);
		gameLoopThread.start();
		
		holder.addCallback(new SurfaceHolder.Callback() {

			@Override
			public void surfaceDestroyed(SurfaceHolder holder) {
				gameEngine.setPaused(true);
			}

			@Override
			public void surfaceCreated(SurfaceHolder holder) {

				if (gameEngine == null) {
					setGameEngine(new BlueSquireEngine(getWidth(), getHeight()));
					gameEngine.initGame();
				} else
					gameEngine.setPaused(false);

				gameLoopThread.setRunning(true);
				setWillNotDraw(false);
			}

			@Override
			public void surfaceChanged(SurfaceHolder holder, int format,
					int width, int height) {
		        Canvas c = 	getHolder().lockCanvas();
		        onDraw(c);
		        getHolder().unlockCanvasAndPost(c);
			}

		});
		this.requestFocus();
		this.setFocusableInTouchMode(true);
		gestureDetector = new GestureDetector(this.getContext(),
				new BlueSquireGestureDetector());
	}
	
	public void gameOver(Canvas canvas) {
		String msg;
		if (gameEngine.getTotalHitPoints() == 0) {
			msg = "Level "+ gameEngine.getLevel() +" finished!";
		} else if (gameEngine.getLives() == 0) {
			msg = "Game Over - Click to play again";
		} else
			msg = "Lost life! Watch out";
		Paint paint = new Paint();

		paint.setColor(Color.WHITE);
		paint.setTextSize(16); 
		canvas.drawText(msg, (getWidth()) / 3, getHeight() / 2, paint);

	}

	@Override
	public void onDraw(Canvas canvas) {

		canvas.drawColor(Color.BLACK);

		if (gameEngine.isInGame()) {
			Paint paint = new Paint();
			canvas.drawBitmap(backgroundImage,
				 getLeft(), getTop(),
					paint);
			paint.setTextSize(16); 
			synchronized (this) {
				if (!gameEngine.getBricks().isEmpty()) {
					for (Brick wall : gameEngine.getBricks())
						if (wall != null && wall.getHitPoints() > 0) {
							switch (wall.getHitPoints()) {
							case 4:
								canvas.drawBitmap(brickImage,
										(int) wall.getX(), (int) wall.getY(),
										paint);
								break;
							case 3:
								canvas.drawBitmap(brickImage2,
										(int) wall.getX(), (int) wall.getY(),
										paint);
								break;
							case 2:
								canvas.drawBitmap(brickImage3,
										(int) wall.getX(), (int) wall.getY(),
										paint);
								break;
							case 1:
								canvas.drawBitmap(brickImage4,
										(int) wall.getX(), (int) wall.getY(),
										paint);
								break;
							}
						}
					if (!gameEngine.getPowerUps().isEmpty()) {
						for (Goodie goo : gameEngine.getPowerUps()) {
							if (goo.isActive()) {
								if (goo.getType() == GoodieType.PLASMA_BALL)
									canvas.drawBitmap(greenPowerUpImage,
											(int) goo.getX(), (int) goo.getY(),
											paint);
								if (goo.getType() == GoodieType.FINISH_LEVEL)
									canvas.drawBitmap(plasmaImage,
											(int) goo.getX(), (int) goo.getY(),
											paint);
								if (goo.getType() == GoodieType.EXTRA_POINTS)
									canvas.drawBitmap(moneyImage,
											(int) goo.getX(), (int) goo.getY(),
											paint);

								if (goo.getType() == GoodieType.EXTRA_LIFE)
									canvas.drawBitmap(paddleIcon,
											(int) goo.getX(), (int) goo.getY(),
											paint);
								if (goo.getType() == GoodieType.SPLIT_BALLS)
									canvas.drawBitmap(threeBall,
											(int) goo.getX(), (int) goo.getY(),
											paint);
								if (goo.getType() == GoodieType.DEATH)
									canvas.drawBitmap(skullImage,
											(int) goo.getX(), (int) goo.getY(),
											paint);
								if (goo.getType() == GoodieType.ENLARGE)
									canvas.drawBitmap(arrowImage,
											(int) goo.getX(), (int) goo.getY(),
											paint);
							}
						}
					}
				}
			}
			if (gameEngine.isEnlarged()){
				canvas.drawBitmap(paddleLarge, gameEngine.getPlayerX(),
						gameEngine.getPlayerY(), paint);
			}else{
			canvas.drawBitmap(paddleImage, gameEngine.getPlayerX(),
					gameEngine.getPlayerY(), paint);
			}
			for (Ball ball : gameEngine.getBalls()) {
				if (gameEngine.isBreakerBall()) {
					canvas.drawBitmap(plasmaBallImage, (int) ball.getX(),
							(int) ball.getY(), paint);
				} else {
					canvas.drawBitmap(ballImage, (int) ball.getX(),
							(int) ball.getY(), paint);
				}
			}
			
			

			paint.setColor(Color.BLUE);
			String msg = "Score: " + gameEngine.getPoints() + " Level: "
					+ gameEngine.getLevel();
			canvas.drawText(msg, 20, 20, paint);

			msg = "Lives: " + gameEngine.getLives() + " X ";
			canvas.drawText(msg, getWidth()*3/4, 20, paint);
			paint.setColor(Color.BLACK);

			canvas.drawBitmap(paddleIcon, getWidth()*3/4 + 40, 8, paint);

		} else
			gameOver(canvas);
		}
	
	@Override
	/**
	 * View component On Touch listener method
	 */
	public synchronized boolean onTouchEvent(MotionEvent e) {
		if (!gameEngine.isInGame()) {
			if (gameEngine.getTotalHitPoints() == 0) {
				gameEngine.setLevel(gameEngine.getLevel() + 1);
				if (gameEngine.getLevel() == BlueLevels.LEVELS.length)
					gameEngine.setLevel(0);

				gameEngine.initLevel(gameEngine.getLevel(), false);
			} else {
				if (gameEngine.getLives() == 0)
					gameEngine.initGame();
				else
					gameEngine.initLevel(gameEngine.getLevel(), true);
				;
			}

			return true;
		}
		else {
			return  gestureDetector.onTouchEvent(e);
			}
		

	}
	
	public BlueSquireEngine getGameEngine() {
		return gameEngine;
	}

	public void setGameEngine(BlueSquireEngine gameEngine) {
		this.gameEngine = gameEngine;
	}

	class BlueSquireGestureDetector extends SimpleOnGestureListener {

		@Override
		public boolean onDown(MotionEvent e1) {
			return true;

		}

		@Override
		public boolean onDoubleTap(MotionEvent e) {
			gameEngine.launchBall(e.getX(), e.getY());
			return true;
		}

		@Override
		public boolean onSingleTapConfirmed(MotionEvent e) {
			gameEngine.launchBall(e.getX(), e.getY());
			return true;
		}
        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        	gameEngine.relocatePaddle(e2.getX(), e2.getY());
            return true;
        }
	}

}
